package com.cupdata.zicon.dbesb;

import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.cupdata.zicon.dbesb.client.OnlineTransDemo20;
import com.cupdata.zicon.dbesb.util.DateUtil;
import com.cupdata.zicon.dbesb.util.SignUtil_lj;
import net.sf.json.JSONObject;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.client.RestTemplate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
 * Created by cuilijin on 2017/6/26.
 */
@SpringBootConfiguration
public class HttpsTransApplication {


    public static void main(String[] args) {
        SpringApplication.run(HttpsTransApplication.class, args);

        try {

            testBalanceQuery();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //static String uri = "https://test.credit2go.cn/escrow/p2p/online";
    static String uri = "https://test.credit2go.cn/escrowsr/p2p/online";
    //	static String uri = "https://access.credit2go.cn/escrow/p2p/online";
    //static String uri = "http://192.168.3.22:7080/escrow2/p2p/online";
    private static final String VERSION = "10";

    private static final String BANKCODE = "65264331";
    private static final String INSTCODE = "80048001";
    private static final String COINSTCHANNEL = "000002";
    private static final String SOURCE = "PX";
    private static final String PRODUCT = "0034";
    private static final String FUISSUER = "JM";

    public static void testBalanceQuery() throws Exception{
        Map<String, Object> reqMap =new TreeMap<>();
        reqMap.put("version", "10");
        reqMap.put("txCode", "balanceQuery");
        reqMap.put("instCode", INSTCODE);
        reqMap.put("bankCode", BANKCODE);
        reqMap.put("txDate", DateUtil.getDate());
        reqMap.put("txTime", DateUtil.getTime());
        reqMap.put("seqNo", "018960");
        reqMap.put("channel", COINSTCHANNEL);
        reqMap.put("accountId", "1017061023504435197");

        testCommon(reqMap);
    }


    public static void testCommon(Map<String, Object> reqMap) throws Exception{
        RestTemplate restTemplate = new RestTemplate(new ArrayList<HttpMessageConverter<?>>(){{add(new FastJsonHttpMessageConverter());}});
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        String requestMapMerged = mergeMap(reqMap);
        System.out.println("requestMapMerged:  "+ requestMapMerged);

        //处理签名
        String sign = SignUtil_lj.sign(requestMapMerged);
        System.out.println("签名:" + sign);
        reqMap.put("sign", sign);
        System.out.println("签名成功");

        headers.set("Accept-Charset", "UTF-8");
        headers.set("contentType","application/json");
        trustAllHttpsCertificates();
        HttpsURLConnection.setDefaultHostnameVerifier(hv);

        HttpEntity entity = new HttpEntity(reqMap,headers);

        System.out.println("发送请求至："+uri);

        ResponseEntity response  = restTemplate.exchange(uri, HttpMethod.POST, entity, Map.class);

        //响应报文
        System.out.println(response.getBody());
        Map responseMap = (Map)response.getBody();

        JSONObject paramsJson = JSONObject.fromObject(responseMap);

        //验签
        String responseSign = (String) responseMap.get("sign");
        responseMap.remove("sign");

        String responseMapMerged = mergeMap(new TreeMap(responseMap));

        System.out.println("responseMerged: "+responseMapMerged.toString());

        boolean verifyResult = SignUtil_lj.verify(responseSign, responseMapMerged.toString());
        if (!verifyResult){
            System.out.println("验证签名失败...");
            return;
        } else {
            System.out.println("验证签名成功");
        }

        System.out.println("retCode:" + responseMap.get("retCode"));
        System.out.println("retMsg:"+responseMap.get("retMsg"));
        System.out.println("返回结果:"+responseMap.toString());
    }



    static HostnameVerifier hv = new HostnameVerifier() {
        public boolean verify(String urlHostName, SSLSession session) {
            System.out.println("Warning: URL Host: " + urlHostName + " vs. "
                    + session.getPeerHost());
            return true;
        }
    };

    private static void trustAllHttpsCertificates() throws Exception {
        javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
        javax.net.ssl.TrustManager tm = new OnlineTransDemo20.miTM();
        trustAllCerts[0] = tm;
        javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext
                .getInstance("SSL");
        sc.init(null, trustAllCerts, null);
        HttpsURLConnection.setDefaultSSLSocketFactory(sc
                .getSocketFactory());
    }

    static class miTM implements javax.net.ssl.TrustManager,
            javax.net.ssl.X509TrustManager {
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return null;
        }

        public boolean isServerTrusted(
                java.security.cert.X509Certificate[] certs) {
            return true;
        }

        public boolean isClientTrusted(
                java.security.cert.X509Certificate[] certs) {
            return true;
        }

        public void checkServerTrusted(
                java.security.cert.X509Certificate[] certs, String authType)
                throws java.security.cert.CertificateException {
            return;
        }

        public void checkClientTrusted(
                java.security.cert.X509Certificate[] certs, String authType)
                throws java.security.cert.CertificateException {
            return;
        }

    }

    public static String mergeMap(Map map ) {
        Map reqMap = new TreeMap(map);

        String requestMerged = "";
        StringBuffer buff = new StringBuffer();
        Iterator<Map.Entry<String, String>> iter = reqMap.entrySet().iterator();
        Map.Entry<String, String> entry;
        while (iter.hasNext()) {
            entry = iter.next();
            if (!"sign".equals(entry.getKey())) {
                if(entry.getValue()==null){
                    entry.setValue("");
                    buff.append("");
                }else{
                    if("subPacks".equalsIgnoreCase(entry.getKey()) ){
                        StringBuffer substr = null;
                        if(reqMap.get("subPacks") != null){
                            substr  = new StringBuffer();

                            List<Map> submapList = (List<Map>)reqMap.get("subPacks");
                            for(Map submap : submapList){
                                substr.append(mergeMap(submap));
                            }
                        }
                        buff.append(String.valueOf(substr.toString()));
                    }else{
                        buff.append(String.valueOf(entry.getValue()));
                    }
                }
            }
        }
        requestMerged = buff.toString();
        return requestMerged;
    }
}